import {
  axiosRenameTask,
  postChangeTaskDate,
  postCreateSubTask,
  postCreateTask,
  postDeleteTask,
  postGetTask,
  postMoveTask,
  postPinTask,
  postPriorityTask,
  postStatusTask,
  postUnpinTask
} from '@/axios/taskBoard';
import { axiosAddFilesTask } from '@/axios/taskBoard/files/files';
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';

export const getTask = createAsyncThunk('task/getTask', async (id: number) => {
  const response = await postGetTask({ params: { id } });
  return response;
});

export const addTask = createAsyncThunk(
  'tasks/addTask',
  async ({ columnId, other }: { columnId: string; other: any }) => {
    const lcls = localStorage.getItem('selectedProjectId') || '';
    const response = await postCreateTask({
      params: { project_id: lcls, column_id: columnId, ...other }
    });
    return { response, columnId };
  }
);

export const addSubTask = createAsyncThunk(
  'tasks/addSubTask',
  async ({ parentId, columnId, other, checklist = false }: any) => {
    const lcls = localStorage.getItem('selectedProjectId') || '';
    const response = await postCreateSubTask({
      params: { ...other, parent_id: parentId, project_id: lcls }
    });
    return { response, columnId, parentId, checklist };
  }
);

export const addSubTaskChecklist = createAsyncThunk(
  'tasks/addSubTaskChecklist',
  async ({ parentId, columnId, other, grandParentId }: any) => {
    const lcls = localStorage.getItem('selectedProjectId') || '';
    const response = await postCreateSubTask({
      params: { ...other, parent_id: parentId, project_id: lcls }
    });
    return { response, columnId, parentId, grandParentId };
  }
);

export const removeTaskItem = createAsyncThunk(
  'task/removeTaskItem',
  async ({
    id,
    columnId,
    parentId,
    grandParentId
  }: {
    id: number;
    columnId?: number;
    parentId?: number;
    grandParentId?: number;
  }) => {
    await postDeleteTask({ params: { id } });
    return { columnId, id, parentId, grandParentId };
  }
);

export const addFileTask = createAsyncThunk(
  'tasks/addFileTask',
  async ({
    taskId,
    file,
    colId,
    subtaskId
  }: {
    taskId: number;
    file: FormData;
    colId: number;
    subtaskId?: number;
  }) => {
    const res = await axiosAddFilesTask({ params: file });
    return { res, taskId, colId, subtaskId };
  }
);

type MoveTask = {
  taskId: number;
  colId: number;
  taskNewIndex: number;
  taskOldIndex: number;
};
export const moveTask = createAsyncThunk(
  'task/moveTaskItem',
  async ({ taskId, colId, taskNewIndex = 0, taskOldIndex }: MoveTask) => {
    postMoveTask({
      params: {
        task_id: +taskId,
        column_id: colId,
        project_id: localStorage.getItem('selectedProjectId') || '',
        parent_id: 0,
        position: taskNewIndex
      }
    });
    return { taskId, colId, taskNewIndex, taskOldIndex };
  }
);

type MoveTaskColumn = {
  taskId: number;
  newColId: number;
  oldColId: number;
  taskNewIndex: number;
  taskOldIndex: number;
};

export const moveTaskColumn = createAsyncThunk(
  'task/moveTaskColumn',
  async ({ taskId, oldColId, newColId = 0, taskNewIndex = 0, taskOldIndex }: MoveTaskColumn) => {
    postMoveTask({
      params: {
        task_id: +taskId,
        column_id: newColId,
        project_id: localStorage.getItem('selectedProjectId') || '',
        parent_id: 0,
        position: taskNewIndex
      }
    });

    return { taskId, oldColId, newColId, taskNewIndex, taskOldIndex };
  }
);

export interface StatusTask {
  status: 0 | 1;
  colId: number;
  taskId: number;
  subtaskId?: number;
  checkId?: number;
}

const changeStatusTask = ({ id, status }: { id: number; status: number }) =>
  postStatusTask({ params: { id, status } });

export const toggleStatusTask = createAsyncThunk(
  'task/toggleStatusTask',
  async ({ status, colId, taskId }: StatusTask) => {
    changeStatusTask({ id: taskId, status });
    return { taskId, colId, status };
  }
);
export const toggleStatusSubtask = createAsyncThunk(
  'task/toggleStatusSubtask',
  async ({ status, colId, taskId, subtaskId }: StatusTask) => {
    if (subtaskId) {
      changeStatusTask({ id: subtaskId, status });
    }
    return { taskId, colId, status, subtaskId };
  }
);

export const toggleStatusChecklist = createAsyncThunk(
  'task/toggleStatusChecklist',
  async ({ status, colId, taskId, subtaskId, checkId }: StatusTask) => {
    if (checkId) {
      changeStatusTask({ id: checkId, status });
    }
    return { status, colId, taskId, subtaskId, checkId };
  }
);

export const renameTask = createAsyncThunk(
  'tasks/renameTask',
  async ({ taskId, name }: { taskId: number; name: string }) => {
    axiosRenameTask({ params: { task_id: taskId, name } });
  }
);

export const pinnedTask = createAsyncThunk(
  'tasks/pinnedTask',
  async ({ taskId, pinned, columnId }: { taskId: number; pinned: 0 | 1; columnId: number }) => {
    if (pinned === 0) {
      postPinTask({ params: { id: taskId } });
    } else {
      postUnpinTask({ params: { id: taskId } });
    }

    return { taskId, pinned, columnId };
  }
);

export const setPriority = createAsyncThunk(
  'task/setPriority',
  async ({
    taskId,
    priority,
    columnId
  }: {
    taskId: number;
    priority: number;
    columnId: number;
  }) => {
    postPriorityTask({ params: { id: taskId, priority_id: priority } });

    return { taskId, priority, columnId };
  }
);

interface TaskDate {
  columnId: number;
  taskId: number;
  date: Date | string;
}

export const changeTaskDate = createAsyncThunk(
  'tasks/changeTaskDate',
  async ({ columnId, taskId, date }: TaskDate) => {
    postChangeTaskDate({
      params: {
        task_id: taskId,
        end_date: date
      }
    });
    return { date, taskId, colId: columnId };
  }
);

interface SubtaskDate extends TaskDate {
  subtaskId: number;
}
export const changeSubtaskDate = createAsyncThunk(
  'tasks/changeSubtaskDate',
  async ({ columnId, taskId, date, subtaskId }: SubtaskDate) => {
    postChangeTaskDate({
      params: {
        task_id: subtaskId,
        end_date: date
      }
    });
    return { date, taskId, colId: columnId, subtaskId };
  }
);

interface ChecklistDate extends SubtaskDate {
  checkId: number;
}
export const changeChecklistDate = createAsyncThunk(
  'tasks/changeChecklistDate',
  async ({ columnId, taskId, date, subtaskId, checkId }: ChecklistDate) => {
    postChangeTaskDate({
      params: {
        task_id: checkId,
        end_date: date
      }
    });
    return { date, taskId, colId: columnId, subtaskId, checkId };
  }
);

export interface ProjectsState {
  tasks: Column[];
  error: string | undefined;
  loading: boolean;
  status: 'idle' | 'loading' | 'error' | 'success';
  taskDrawer: Task | null;
}

const initialState: ProjectsState = {
  tasks: [],
  error: undefined,
  loading: false,
  status: 'idle',
  taskDrawer: null
};

const tasksSLice = createSlice({
  name: 'columns',
  initialState: initialState,
  reducers: {},
  extraReducers: (builder) => {
    builder
      .addCase(getTask.pending, (state) => {
        state.status = 'loading';
      })
      .addCase(getTask.fulfilled, (state, action) => {
        state.status = 'success';
        state.taskDrawer = action.payload;
      })
      .addCase(getTask.rejected, (state) => {
        state.status = 'error';
      });
  }
});

export default tasksSLice.reducer;
